package com.xpf.controller;

import com.xpf.enums.YesOrNo;
import com.xpf.pojo.Carousel;
import com.xpf.pojo.Category;
import com.xpf.pojo.vo.CategoryVO;
import com.xpf.pojo.vo.NewItemsVO;
import com.xpf.service.CarouselService;
import com.xpf.service.CategoryService;
import com.xpf.utils.JSONResult;
import com.xpf.utils.JsonUtils;
import com.xpf.utils.RedisOperator;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@Api(value = "首页", tags = {"首页展示的相关接口"})
@RestController //所有请求都是json对象
@RequestMapping("index")
public class IndexController {

    @Autowired
    private CarouselService carouselService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private RedisOperator redisOperator;

    @ApiOperation(value = "获取首页轮播图列表", notes = "获取首页轮播图列表", httpMethod = "GET")
    @GetMapping("/carousel")
    public JSONResult carousel(){

        List<Carousel> carouselList = new ArrayList<>();
        String carouselStr = redisOperator.get("carousel");
        if (StringUtils.isBlank(carouselStr)){
            carouselList = carouselService.queryAll(YesOrNo.YES.type);
            redisOperator.set("carousel", JsonUtils.objectToJson(carouselList));
        }else {
            carouselList = JsonUtils.jsonToList(carouselStr,Carousel.class);
        }

        return JSONResult.ok(carouselList);
    }
    /*
        1.后台运营系统，一旦广告（轮播图）发生更改，就可以删除缓存，然后重置
        2.定时重置，比如每天凌晨三点重置
        3.每个轮播图都有可能是一个广告，每个广告都会有一个过期的时间，过期了，重置
     */

    /*
    首页分类展示需求:
        1、第一次刷新主页查询大分类，渲染展示到首页
        2、如果鼠标上移到大分类，则加载其子分类的内容，如果已经存在子分类，则不需要加载（懒加载模式）
    */
    @ApiOperation(value = "获取商品分类(一级分类)", notes = "获取商品分类(一级分类)", httpMethod = "GET")
    @GetMapping("/cats")
    public JSONResult cats(){
        List<Category> categoryList = new ArrayList<>();

        String catsStr = redisOperator.get("cats");
        if (StringUtils.isBlank(catsStr)){
            categoryList = categoryService.queryAllRootLevelCat();
            redisOperator.set("cats",JsonUtils.objectToJson(categoryList));
        }else {
            categoryList = JsonUtils.jsonToList(catsStr, Category.class);
        }

        return JSONResult.ok(categoryList);
    }

    @ApiOperation(value = "获取商品子分类", notes = "获取商品子分类)", httpMethod = "GET")
    @GetMapping("/subCat/{rootCatId}")
    public JSONResult subCat(
                            @ApiParam(name = "rootCatId", value = "一级分类id", required = true)
                            @PathVariable Integer rootCatId){

        if (rootCatId == null){
            return JSONResult.errorMsg("分类不存在");
        }

        List<CategoryVO> subCatList = new ArrayList<>();
        String catsStr = redisOperator.get("subCat:" + rootCatId);
        if (StringUtils.isBlank(catsStr)){
            subCatList = categoryService.getSubCatList(rootCatId);
            //以下if else 用于防止缓存穿透
            if(subCatList != null && subCatList.size() > 0){
                //根据分类id，从数据库中查询到数据，set到redis中，过期时间默认永久
                redisOperator.set("subCat:"+rootCatId, JsonUtils.objectToJson(subCatList));
            }else {
                //根据分类id，从数据库中查询不到数据，
                // 但是为了防止恶意引起的redis缓存穿透，将null的list也存入到redis中（即[]）
                // 并且设置过期时间。这样就算以后对应的分类id下新增了子分类（db查询有数据），也可以覆盖掉redis中存的[]。
                redisOperator.set("subCat:"+rootCatId, JsonUtils.objectToJson(subCatList), 60*5);
            }

        }else {
            subCatList = JsonUtils.jsonToList(catsStr, CategoryVO.class);
        }

        return JSONResult.ok(subCatList);
    }

    @ApiOperation(value = "查询每个一级分类下的最新的6条商品数据", notes = "查询每个一级分类下的最新的6条商品数据)", httpMethod = "GET")
    @GetMapping("/sixNewItems/{rootCatId}")
    public JSONResult sixNewItems(
            @ApiParam(name = "rootCatId", value = "一级分类id", required = true)
            @PathVariable Integer rootCatId){
        if (rootCatId == null){
            return JSONResult.errorMsg("分类不存在");
        }
        List<NewItemsVO> sixNewItemsLazy = categoryService.getSixNewItemsLazy(rootCatId);
        return JSONResult.ok(sixNewItemsLazy);
    }

}
